#include <iostream>

#include "formula.hpp"
#include "formula_callable.hpp"
#include "item_type.hpp"
#include "wml_node.hpp"
#include "wml_utils.hpp"

namespace {
std::map<std::string, item_type_ptr> items;
}

void item_type::init(wml::const_node_ptr node)
{
	wml::node::const_child_iterator i1 = node->begin_child("item");
	wml::node::const_child_iterator i2 = node->end_child("item");
	for(; i1 != i2; ++i1) {
		item_type_ptr new_item(new item_type(i1->second));
		items[new_item->id()] = new_item;
	}
}

const_item_type_ptr item_type::get(const std::string& key)
{
	return items[key];
}

item_type::item_type(wml::const_node_ptr node)
  : id_(node->attr("id")), spoil_formula_(game_logic::formula::create_optional_formula(node->attr("spoil_formula"))),
    downgrades_to_(node->attr("downgrades_to")),
    upgrades_to_(node->attr("upgrades_to")),
    combines_with_(node->attr("combines_with"))
{
}

namespace {
class spoils_callable : public game_logic::formula_callable
{
public:
	explicit spoils_callable(bool used) : used_(used)
	{}

	variant get_value(const std::string& key) const {
		if(key == "used") {
			return variant(used_);
		} else {
			return variant();
		}
	}
private:
	bool used_;
};
}

bool item_type::spoils(bool used) const
{
	if(!spoil_formula_) {
		return false;
	}
	spoils_callable callable(used);
	return spoil_formula_->execute(callable).as_bool();
}

bool item_type::spoilable() const
{
	return spoil_formula_;
}
